package com.edmendst.xmall.service.impl;

import com.edmendst.xmall.dto.DeliveryInfo;
import com.edmendst.xmall.dto.LoginRequest;
import com.edmendst.xmall.dto.UserInFo;
import com.edmendst.xmall.dto.UserTypeTranslate;
import com.edmendst.xmall.mapper.UserAddressMapper;
import com.edmendst.xmall.mapper.UserMapper;
import com.edmendst.xmall.pojo.User;
import com.edmendst.xmall.pojo.UserAddress;
import com.edmendst.xmall.pojo.UserExample;
import com.edmendst.xmall.security.PasswordSecurity;
import com.edmendst.xmall.service.UserService;
import com.edmendst.xmall.util.JWTUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class UserServiceImpl implements UserService {

    @Value("${upload.path}")
    private String IMAGE_PATH;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserAddressMapper userAddressMapper;

    @Autowired
    private JWTUtil jwtUtil;

    @Autowired
    private ObjectMapper objectMapper;

    @Qualifier("redisTemplate")
    @Autowired
    private RedisTemplate redisTemplate;

    //用户注册
    @Override
    public String register(@Valid User user) {
        // 检查用户名是否已存在
        UserExample userExample = new UserExample();
        userExample.createCriteria().andUserNameEqualTo(user.getUserName());
        List<User> usersByUsername = userMapper.selectByExample(userExample);
        if (!usersByUsername.isEmpty()) {
            System.out.println("用户名已存在");
            return "注册失败：用户名已存在";
        }

        // 检查邮箱是否已存在

        userExample.createCriteria().andUserEmailEqualTo(user.getUserEmail());
        List<User> usersByEmail = userMapper.selectByExample(userExample);
        if (!usersByEmail.isEmpty()) {
            System.out.println("用户名已存在");
            return "注册失败：邮箱已存在";
        }

        // 如果用户名和邮箱都不存在，则插入新用户
        try {
            String userPassword = user.getUserPassword();
            PasswordSecurity passwordSecurity = new PasswordSecurity();
            String encodedPassword = passwordSecurity.encodePassword(userPassword);
            user.setUserPassword(encodedPassword);
            user.setUserType("buyer");
            userMapper.insert(user);
            return "注册成功";
        } catch (Exception e) {
            e.printStackTrace();
            return "注册失败：服务器错误";
        }
    }

    //登录
    @Override
    public String login(LoginRequest loginRequest) {
        String userName = loginRequest.getUserName();
        String userPassword = loginRequest.getUserPassword();

        UserExample userExample = new UserExample();
        userExample.createCriteria().andUserNameEqualTo(userName);
        List<User> users = userMapper.selectByExample(userExample);
        if (users.isEmpty()) {
            System.out.println("用户名不存在");
            return "用户名不存在";
        } else {
            User user = users.get(0);
            PasswordSecurity passwordSecurity = new PasswordSecurity();
            boolean matches = passwordSecurity.matchPassword(userPassword, user.getUserPassword());
            if (matches) {
                String userType = user.getUserType();
                String generateToken = jwtUtil.generateToken(userName, userType);
//                System.out.println("生成的Token：" + generateToken); // 添加日志
                return StringUtils.hasText(generateToken) ? generateToken : "令牌生成失败";
            } else {
                System.out.println("密码错误");
                return "密码错误";
            }
        }
    }

    @Override
    public String logout(String token) {

        long remainingTime = jwtUtil.getRemainingTime(token);
        if (remainingTime <= 0) {
            return "令牌已过期";
        }
        String key = "jwt:blacklist:" + token;
        redisTemplate.opsForValue().set(key, "blacklisted", remainingTime, TimeUnit.MILLISECONDS);
        return "已经加入黑名单";
    }

    //个人信息
    @Override
    public UserInFo selectUserByUserName(String userName) {

        UserInFo userInFo = new UserInFo();
        //查找userinfo

        UserExample userExample = new UserExample();
        userExample.createCriteria().andUserNameEqualTo(userName);
        List<User> users = userMapper.selectByExample(userExample);

        userInFo.setUserId(users.get(0).getUserId());
        userInFo.setUserName(users.get(0).getUserName());
        userInFo.setUserNickname(users.get(0).getUserNickname());
        userInFo.setUserImage(users.get(0).getUserImage());
        userInFo.setUserSignature(users.get(0).getUserSignature());
        userInFo.setUserEmail(users.get(0).getUserEmail());
        userInFo.setUserType(users.get(0).getUserType());

        if (users.isEmpty()) {
            System.out.println("用户名不存在");
            return null;
        }
        return userInFo;
    }

    //修改昵称
    @Override
    public int updateUserNickname(String userNickname, String userName) {

        UserExample userExample = new UserExample();
        userExample.createCriteria().andUserNameEqualTo(userName);
        if (!userExample.getOredCriteria().isEmpty()) {
            List<User> users = userMapper.selectByExample(userExample);
            if (users.isEmpty()) {
                System.out.println("用户名不存在");
                return 0;
            }
            User user = new User();
            user.setUserNickname(userNickname);
            int i = userMapper.updateByExampleSelective(user, userExample);
            return i;
        }
        return 0;
    }

    //修改签名
    @Override
    public int updateUserSignature(String userSignature, String userName) {

        UserExample userExample = new UserExample();
        userExample.createCriteria().andUserNameEqualTo(userName);
        if (!userExample.getOredCriteria().isEmpty()) {
            List<User> users = userMapper.selectByExample(userExample);
            if (users.isEmpty()) {
                System.out.println("用户不存在");
                return 0;
            }
            User user = new User();
            user.setUserSignature(userSignature);
            int i = userMapper.updateByExampleSelective(user, userExample);
            return i;
        }
        return 0;
    }


    //修改头像

    @Override
    public int updateUserImage(MultipartFile userImage, String userName) {
        final String[] ALLOWED_EXT = {".png", ".jpg", ".jpeg", ".gif"};

        UserExample example = new UserExample();
        example.createCriteria().andUserNameEqualTo(userName);
        List<User> users = userMapper.selectByExample(example);
        if (users.isEmpty()) return 0;

        try {
            // 校验文件类型
            String fileName = userImage.getOriginalFilename();
            String fileExt = fileName.substring(fileName.lastIndexOf(".")).toLowerCase();
            if (!Arrays.asList(ALLOWED_EXT).contains(fileExt)) {
                throw new IllegalArgumentException("不支持的文件类型");
            }

            // 构建存储目录 (格式: userImage/username/)
            Path targetDir = Paths.get(IMAGE_PATH, userName);
            Files.createDirectories(targetDir);

            // 生成唯一文件名
            String newFileName = UUID.randomUUID() + fileExt;
            Path targetPath = targetDir.resolve(newFileName);

            // 保存文件
            try (InputStream is = userImage.getInputStream()) {
                Files.copy(is, targetPath, StandardCopyOption.REPLACE_EXISTING);
            }

            // 保存相对路径到数据库
            String relativePath = userName + "/" + newFileName;
            User user = new User();
            user.setUserImage(relativePath);  // 只保存相对路径
            return userMapper.updateByExampleSelective(user, example);

        } catch (IOException e) {
            throw new RuntimeException("文件上传失败: " + e.getMessage());
        }
    }

    @Override
    public int updateUserPassword(String userPassword1, String userPassword2, String userName) {

        UserExample userExample = new UserExample();
        userExample.createCriteria().andUserNameEqualTo(userName);

        PasswordSecurity passwordSecurity = new PasswordSecurity();
        if (!userExample.getOredCriteria().isEmpty()) {

            List<User> users = userMapper.selectByExample(userExample);

            if (users.isEmpty()) {
                System.out.println("用户名不存在");
                return 0;
            }
            // 获取数据库中的加密密码
            String storedHash = users.get(0).getUserPassword();
            if (passwordSecurity.matchPassword(userPassword1, storedHash)) {
                User user = new User();
                // 加密新密码
                String encodedPassword = passwordSecurity.encodePassword(userPassword2);
                user.setUserPassword(encodedPassword);
                int i = userMapper.updateByExampleSelective(user, userExample);
                return i;
            }
        }
        return 0;
    }

    //修改用户类型(卖方）
    @Override
    public String updateUserType(UserTypeTranslate userTypeTranslate) {

        List<String> allowedTypes = Arrays.asList("buyer", "seller", "both");
        if (!allowedTypes.contains(userTypeTranslate.getUserType().toLowerCase())) {
            throw new IllegalArgumentException("非法的用户类型");
        }

        UserExample userExample = new UserExample();
        userExample.createCriteria().andUserNameEqualTo(userTypeTranslate.getUserName());
        User user = new User();
        user.setUserType(userTypeTranslate.getUserType());
        int i = userMapper.updateByExampleSelective(user, userExample);
        SecurityContextHolder.clearContext(); // 清除当前认证
        if (i == 1) {
            return "修改成功，请重新登录";
        }
        return "修改失败";
    }


    @Override
    public Integer selectUserIdByUserName(String userName) {
        UserExample userExample = new UserExample();
        userExample.createCriteria().andUserNameEqualTo(userName);
        List<User> users = userMapper.selectByExample(userExample);
        if (users.size() == 1) {
            return users.get(0).getUserId();
        }
        return 0;
    }

    @Override
    public int addDeliveryInfo(String userName, DeliveryInfo deliveryInfo) throws JsonProcessingException {
        Integer userId = selectUserIdByUserName(userName);
        if (userId == null || userId == 0) return 0;

        UserAddress address = new UserAddress();
        address.setUserId(userId);
        address.setReceiverName(deliveryInfo.getReceiver());
        address.setMobile(String.valueOf(deliveryInfo.getMobile()));
        address.setRegion(deliveryInfo.getRegion());
        address.setDetailAddress(deliveryInfo.getDetail());

        // 如果是第一个地址则设为默认
        boolean isEmpty = userAddressMapper.selectCountByUserId(userId) == 0;
        address.setIsDefault(isEmpty);
        int result = userAddressMapper.insert(address);

        // 更新user表的默认地址信息
        if (address.getIsDefault()) {
            updateUserDeliveryInfo(userId, address);
        }
        return result;
    }

    @Override
    @Transactional // 添加事务注解
    public int updateDefaultAddress(String userName, Long addressId) throws JsonProcessingException {
        Integer userId = selectUserIdByUserName(userName);
        if (userId == null || userId == 0) return 0;

        // 校验地址归属
        UserAddress address = userAddressMapper.selectByPrimaryKey(addressId);
        if (address == null || !address.getUserId().equals(userId)) {
            throw new SecurityException("Address not belong to user");
        }

        // 1. 清除所有默认地址标记
        userAddressMapper.clearDefaultAddresses(userId);

        // 2. 设置新默认地址
        UserAddress updateParam = new UserAddress();
        updateParam.setAddressId(addressId);
        updateParam.setIsDefault(true);
        int result = userAddressMapper.updateByPrimaryKeySelective(updateParam);

        // 3. 获取最新地址数据更新user表
        UserAddress updatedAddress = userAddressMapper.selectByPrimaryKey(addressId);
        updateUserDeliveryInfo(userId, updatedAddress);

        return result;
    }

    // 辅助方法：更新user表的配送信息
    private void updateUserDeliveryInfo(Integer userId, UserAddress address) throws JsonProcessingException {
        DeliveryInfo deliveryInfo = new DeliveryInfo();
        deliveryInfo.setAddressId(address.getAddressId());
        deliveryInfo.setReceiver(address.getReceiverName());
        deliveryInfo.setMobile(address.getMobile());
        deliveryInfo.setRegion(address.getRegion());
        deliveryInfo.setDetail(address.getDetailAddress());
        deliveryInfo.setDefaultAddress(true);

        User user = new User();
        user.setUserId(userId);
        user.setDeliveryInfo(objectMapper.writeValueAsString(deliveryInfo));
        userMapper.updateByPrimaryKeySelective(user);
    }

    @Override
    public List<DeliveryInfo> getAllDeliveryInfoList(String userName) {
        Integer userId = selectUserIdByUserName(userName);
        if (userId == null || userId == 0) return Collections.emptyList();

        return userAddressMapper.selectAllByUserId(userId).stream()
                .map(address -> new DeliveryInfo(
                        address.getAddressId(),
                        address.getReceiverName(),  // receiverName → receiver
                        address.getMobile(),
                        address.getRegion(),
                        address.getDetailAddress(), //detailAddress → detail
                        address.getIsDefault()      //isDefault → defaultAddress
                )).collect(Collectors.toList());
    }

}
